package com.hrzyit.whistle.im.widgets

import android.annotation.SuppressLint
import android.annotation.TargetApi
import android.app.Activity
import android.content.Context
import android.content.SharedPreferences
import android.graphics.Rect
import android.os.Build
import android.os.Environment
import android.support.v4.view.ViewPager
import android.text.Editable
import android.text.TextWatcher
import android.util.DisplayMetrics
import android.util.Log
import android.view.Gravity
import android.view.MotionEvent
import android.view.View
import android.view.WindowManager
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import com.hrzyit.base.utils.AudioRecorderUtils
import com.hrzyit.base.utils.DateUtils
import com.hrzyit.base.utils.IMUtils
import com.hrzyit.whistle.im.R
import com.hrzyit.whistle.im.entity.MessageInfo
import com.hrzyit.whistle.im.util.PopupWindowFactory
import org.greenrobot.eventbus.EventBus
import java.io.File

/**
 * 输入框管理类
 */
class EmotionInputDetector private constructor() {

    private var mActivity: Activity? = null
    private var mInputManager: InputMethodManager? = null
    private var sp: SharedPreferences? = null
    private var mEmotionLayout: View? = null
    private var mEditText: EditText? = null
    private var mVoiceText: TextView? = null
    private var mContentView: View? = null
    private var mViewPager: ViewPager? = null
    private var mSendButton: View? = null
    private var mAddButton: View? = null
    private var isShowEmotion: Boolean? = false
    private var isShowAdd: Boolean? = false
    private var mAudioRecorderUtils: AudioRecorderUtils? = null
    private var mVoicePop: PopupWindowFactory? = null
    private var mPopVoiceText: TextView? = null

    private val isSoftInputShown: Boolean
        get() = supportSoftInputHeight != 0

    private// When SDK Level >= 20 (Android L), the softInputHeight will contain the height of softButtonsBar (if has)
    val supportSoftInputHeight: Int
        get() {
            val r = Rect()
            mActivity!!.window.decorView.getWindowVisibleDisplayFrame(r)
            val screenHeight = mActivity!!.window.decorView.rootView.height
            var softInputHeight = screenHeight - r.bottom
            if (Build.VERSION.SDK_INT >= 20) {
                softInputHeight = softInputHeight - softButtonsBarHeight
            }
            if (softInputHeight < 0) {
                Log.w("EmotionInputDetector", "Warning: value of softInputHeight is below zero!")
            }
            if (softInputHeight > 0) {
                sp!!.edit().putInt(SHARE_PREFERENCE_TAG, softInputHeight).apply()
            }
            return softInputHeight
        }

    private val softButtonsBarHeight: Int
        @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
        get() {
            val metrics = DisplayMetrics()
            mActivity!!.windowManager.defaultDisplay.getMetrics(metrics)
            val usableHeight = metrics.heightPixels
            mActivity!!.windowManager.defaultDisplay.getRealMetrics(metrics)
            val realHeight = metrics.heightPixels
            return if (realHeight > usableHeight) {
                realHeight - usableHeight
            } else {
                0
            }
        }

    fun bindToContent(contentView: View): EmotionInputDetector {
        mContentView = contentView
        return this
    }

    @SuppressLint("ClickableViewAccessibility")
    fun bindToEditText(editText: EditText): EmotionInputDetector {
        mEditText = editText
        mEditText!!.requestFocus()
        mEditText!!.setOnTouchListener { v, event ->
            if (event?.action == MotionEvent.ACTION_UP && mEmotionLayout!!.isShown) {
                lockContentHeight()
                hideEmotionLayout(true)

                mEditText!!.postDelayed({ unlockContentHeightDelayed() }, 200L)
            }
            false
        }
//        mEditText!!.setOnTouchListener { v, event ->
//            if (event.action == MotionEvent.ACTION_UP && mEmotionLayout!!.isShown) {
//                lockContentHeight()
//                hideEmotionLayout(true)
//
//                mEditText!!.postDelayed({ unlockContentHeightDelayed() }, 200L)
//            }
//            false
//        }

        mEditText!!.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {

            }

            override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
                if (s.length > 0) {
//                    mAddButton!!.visibility = View.GONE
                    mSendButton!!.visibility = View.VISIBLE
                } else {
//                    mAddButton!!.visibility = View.VISIBLE
                    mSendButton!!.visibility = View.GONE
                }
            }

            override fun afterTextChanged(s: Editable) {

            }
        })

        return this
    }

    fun bindToEmotionButton(emotionButton: View): EmotionInputDetector {
        emotionButton.setOnClickListener {
            if (mEmotionLayout!!.isShown) {
                if (isShowAdd!!) {
                    mViewPager!!.currentItem = 0
                    isShowEmotion = true
                    isShowAdd = false
                } else {
                    lockContentHeight()
                    hideEmotionLayout(true)
                    isShowEmotion = false
                    unlockContentHeightDelayed()
                }
            } else {
                if (isSoftInputShown) {
                    lockContentHeight()
                    showEmotionLayout()
                    unlockContentHeightDelayed()
                } else {
                    showEmotionLayout()
                }
                mViewPager!!.currentItem = 0
                isShowEmotion = true
            }
        }
        return this
    }

    fun bindToAddButton(addButton: View): EmotionInputDetector {
        mAddButton = addButton
        addButton.setOnClickListener {
            if (mEmotionLayout!!.isShown) {
                if (isShowEmotion!!) {
                    mViewPager!!.currentItem = 1
                    isShowAdd = true
                    isShowEmotion = false
                } else {
                    lockContentHeight()
                    hideEmotionLayout(true)
                    isShowAdd = false
                    unlockContentHeightDelayed()
                }
            } else {
                if (isSoftInputShown) {
                    lockContentHeight()
                    showEmotionLayout()
                    unlockContentHeightDelayed()
                } else {
                    showEmotionLayout()
                }
                mViewPager!!.currentItem = 1
                isShowAdd = true
            }
        }
        return this
    }

    fun bindToSendButton(sendButton: View): EmotionInputDetector {
        mSendButton = sendButton
        sendButton.setOnClickListener {
//            mAddButton!!.visibility = View.VISIBLE
            mSendButton!!.visibility = View.GONE
            val messageInfo = MessageInfo()
            messageInfo.content = mEditText!!.text.toString()
            EventBus.getDefault().post(messageInfo)
            mEditText!!.setText("")
        }
        return this
    }

    fun bindToVoiceButton(voiceButton: View): EmotionInputDetector {
        voiceButton.setOnClickListener {
            hideEmotionLayout(false)
            hideSoftInput()
            mVoiceText!!.visibility = if (mVoiceText!!.visibility == View.GONE) View.VISIBLE else View.GONE
            mEditText!!.visibility = if (mVoiceText!!.visibility == View.GONE) View.VISIBLE else View.GONE
        }
        return this
    }

    fun bindToVoiceText(voiceText: TextView): EmotionInputDetector {
        mVoiceText = voiceText
        mVoiceText!!.setOnTouchListener { v, event ->
            // 获得x轴坐标
            val x = event.x.toInt()
            // 获得y轴坐标
            val y = event.y.toInt()

            when (event.action) {
                MotionEvent.ACTION_DOWN -> {
                    mVoicePop!!.showAtLocation(v, Gravity.CENTER, 0, 0)
                    mVoiceText!!.text = "松开结束"
                    mPopVoiceText!!.text = "手指上滑，取消发送"
                    mVoiceText!!.tag = "1"
                    mAudioRecorderUtils!!.startRecord(mActivity as Context)
                }
                MotionEvent.ACTION_MOVE -> if (wantToCancle(x, y)) {
                    mVoiceText!!.text = "松开结束"
                    mPopVoiceText!!.text = "松开手指，取消发送"
                    mVoiceText!!.tag = "2"
                } else {
                    mVoiceText!!.text = "松开结束"
                    mPopVoiceText!!.text = "手指上滑，取消发送"
                    mVoiceText!!.tag = "1"
                }
                MotionEvent.ACTION_UP -> {
                    mVoicePop!!.dismiss()
                    if (mVoiceText!!.tag == "2") {
                        //取消录音（删除录音文件）
                        mAudioRecorderUtils!!.cancelRecord()
                    } else {
                        //结束录音（保存录音文件）
                        mAudioRecorderUtils!!.stopRecord()
                    }
                    mVoiceText!!.text = "按住说话"
                    mVoiceText!!.tag = "3"
                    mVoiceText!!.visibility = View.GONE
                    mEditText!!.visibility = View.VISIBLE
                }
            }
            true
        }
        return this
    }

    private fun wantToCancle(x: Int, y: Int): Boolean {
        // 超过按钮的宽度
        if (x < 0 || x > mVoiceText!!.width) {
            return true
        }
        // 超过按钮的高度
        return y < -50 || y > mVoiceText!!.height + 50
    }

    fun setEmotionView(emotionView: View): EmotionInputDetector {
        mEmotionLayout = emotionView
        return this
    }

    fun setViewPager(viewPager: ViewPager): EmotionInputDetector {
        mViewPager = viewPager
        return this
    }

    private lateinit var mAudioFile: File
    fun build(): EmotionInputDetector {
        mActivity!!.window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN or WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
        hideSoftInput()
        // 初始化录音文件路径
        createTempFile("file.amr")
        val mAudioFilePath = mAudioFile.absolutePath
        mAudioRecorderUtils = AudioRecorderUtils(mAudioFilePath)

        val view = View.inflate(mActivity, R.layout.layout_microphone, null)
        mVoicePop = PopupWindowFactory(mActivity as Context, view)

        //PopupWindow布局文件里面的控件
        val mImageView = view.findViewById<View>(R.id.iv_recording_icon) as ImageView
        val mTextView = view.findViewById<View>(R.id.tv_recording_time) as TextView
        mPopVoiceText = view.findViewById<View>(R.id.tv_recording_text) as TextView
        //录音回调
        mAudioRecorderUtils!!.setOnAudioStatusUpdateListener(object : AudioRecorderUtils.OnAudioStatusUpdateListener {

            //录音中....db为声音分贝，time为录音时长
            override fun onUpdate(db: Double, time: Long) {
                mImageView.drawable.level = (3000 + 6000 * db / 100).toInt()
                mTextView.text = IMUtils.long2String(time)
            }

            //录音结束，filePath为保存路径
            override fun onStop(time: Long, filePath: String?) {
                mTextView.text = IMUtils.long2String(0)
                val messageInfo = MessageInfo()
                messageInfo.filepath = filePath
                messageInfo.voiceTime = time
                EventBus.getDefault().post(messageInfo)
            }

            override fun onError() {
                mVoiceText!!.visibility = View.GONE
                mEditText!!.visibility = View.VISIBLE
            }

            override fun onCancel(time: Long) {
                mTextView.text = IMUtils.long2String(0)
            }
        })
        return this
    }

    fun interceptBackPress(): Boolean {
        if (mEmotionLayout!!.isShown) {
            hideEmotionLayout(false)
            return true
        }
        return false
    }

    private fun showEmotionLayout() {
        var softInputHeight = supportSoftInputHeight
        if (softInputHeight == 0) {
            softInputHeight = sp!!.getInt(SHARE_PREFERENCE_TAG, 787)
        }
        hideSoftInput()
        mEmotionLayout!!.layoutParams.height = softInputHeight
        mEmotionLayout!!.visibility = View.VISIBLE
    }

    fun hideEmotionLayout(showSoftInput: Boolean) {
        if (mEmotionLayout!!.isShown) {
            mEmotionLayout!!.visibility = View.GONE
            if (showSoftInput) {
                showSoftInput()
            }
        }
    }

    private fun lockContentHeight() {
        val params = mContentView!!.layoutParams as LinearLayout.LayoutParams
        params.height = mContentView!!.height
        params.weight = 0.0f
    }

    private fun unlockContentHeightDelayed() {
        mEditText!!.postDelayed({ (mContentView!!.layoutParams as LinearLayout.LayoutParams).weight = 1.0f }, 200L)
    }

    private fun showSoftInput() {
        mEditText!!.requestFocus()
        mEditText!!.post { mInputManager!!.showSoftInput(mEditText, 0) }
    }

    fun hideSoftInput() {
        mInputManager!!.hideSoftInputFromWindow(mEditText!!.windowToken, 0)
    }

    companion object {

        private val SHARE_PREFERENCE_NAME = "com.dss886.emotioninputdetector"
        private val SHARE_PREFERENCE_TAG = "soft_input_height"

        fun with(activity: Activity): EmotionInputDetector {
            val emotionInputDetector = EmotionInputDetector()
            emotionInputDetector.mActivity = activity
            emotionInputDetector.mInputManager =
                activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
            emotionInputDetector.sp = activity.getSharedPreferences(SHARE_PREFERENCE_NAME, Context.MODE_PRIVATE)
            return emotionInputDetector
        }
    }

    /**
     * 创建上传图片临时文件
     */
    private fun createTempFile(suffix:String) {
        val tempFileName = "${DateUtils.curTime}.$suffix"
        when (Environment.MEDIA_MOUNTED) {
            Environment.getExternalStorageState() -> {
                // 在存储卡中创建
                this.mAudioFile = File(Environment.getExternalStorageDirectory(), tempFileName)
            }
            else -> {
                // 在内存中创建
                this.mAudioFile = File(mActivity!!.filesDir, tempFileName)
            }
        }
    }

}
